#include "../../include/Configuration.h"
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>

using std::cerr;
using std::cout;
using std::endl;
using std::ifstream;
using std::istringstream;
using std::vector;

// 静态数据成员初始化
// 饱汗模式
Configuration* Configuration::_pInstance = nullptr;
pthread_once_t Configuration::_once = PTHREAD_ONCE_INIT;

string Configuration::_filepath = "../conf/search.conf";

Configuration* Configuration::getInstance() {
    pthread_once(&_once, init);
    return _pInstance;
}

void Configuration::init() {
    _pInstance = new Configuration();
    atexit(destroy);
}

void Configuration::destroy() {
    if (_pInstance) {
        delete _pInstance;
        _pInstance = nullptr;
    }
}

Configuration::Configuration() {
    //初始化_configMap
    configMapInit(Configuration::_filepath);
    //初始化_stopWordList
    stopWordListInit();
}

Configuration::~Configuration() {
    /* if (_pInstance) { */
    /*     delete _pInstance; */
    /*     _pInstance = nullptr; */
    /* } */
}

pair<string, string> extractPair(const string& Line) {
    if (Line.empty() || Line[0] == '#') {
        // 如果Line为空或以'#'开头，则跳过该行，返回一个空的pair对象
        return {};
    }
    istringstream iss(Line);
    string word1, word2;
    iss >> word1;
    iss >> word2;
    return {std::move(word1), std::move(word2)};
}

unordered_map<string, string>& Configuration::getConfigMap() {
    return _configMap;
}

string Configuration::getConfigValue(const string& key) {
    return _configMap[key];
}

unordered_set<string>& Configuration::getEnStopWordList() {
    return _enStopWordList;
}

unordered_set<string>& Configuration::getZhStopWordList() {
    return _zhStopWordList;
}

void Configuration::configMapInit(const string& filename) {
    char buf[1024] ={0};
    ifstream ifs("../conf/search.conf");
    if (!ifs.is_open()) {
        cerr << "Failed to open config " << filename << 
            ", the pwd is " << buf << "." << endl;
        return;
    }

    ifs.seekg(std::ios_base::beg);
    string Line;
    while (getline(ifs, Line)) {
        _configMap.emplace(extractPair(Line));
    }

    ifs.close();
}

void extractStopWord(const string& filepath, unordered_set<string>& stopWordList) {
    ifstream ifs(filepath);
    if (!ifs.is_open()) {
        cerr << "Failed to open " << filepath << endl;
        return;
    }

    ifs.seekg(std::ios_base::beg);
    string stopWord;
    while (getline(ifs, stopWord)) {
        stopWordList.insert(stopWord);
    }

    ifs.close();
}

void Configuration::stopWordListInit() {
    extractStopWord(_configMap["STOP_WORDS_LIST_ENG_PATH"], _enStopWordList);
    extractStopWord(_configMap["STOP_WORDS_LIST_CN_PATH"], _zhStopWordList);
}

